﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Web.Security;
using System.Data.SqlClient;
using System.Configuration;

namespace SqlMembershiProviderExtended
{

    /// <summary>SqlMembershipProvider class extended.</summary>
    public sealed class SqlMembershipProviderExt : SqlMembershipProvider
    {
        #region Fields
        string _sqlConnectionStringName;
        string _sqlConnectionString;
        string _applicationName;
        #endregion

        /// <summary>
        /// This method is called during the initializing of the provider. Receives an object
        /// with the configuration values.
        /// </summary>
        /// <param name="name">Provider name</param>
        /// <param name="config">Configuration values collection.</param>
        public override void Initialize( string name, System.Collections.Specialized.NameValueCollection config )
        {
            //Obtiene y mantiene los valores de la configuración del proveedor.
            _sqlConnectionStringName = config["connectionStringName"].ToString( );
            _sqlConnectionString = ConfigurationManager.ConnectionStrings[_sqlConnectionStringName].ToString();
            _applicationName = config["applicationName"].ToString( );
            base.Initialize( name, config );
        }
        /// <returns>Devuelve el identificador del segmento creado.</returns>
        /// <summary>
        /// Crea un nuevo segmento, por defecto los nuevos segmento se crean con el valor
        /// predeterminado "FlagDeleted" a False.
        /// </summary>
        /// <remarks>
        /// El valor de ordenamiento de cada grupo de segmentos creado se establece
        /// automáticamente al crearlo con el valor máximo existente
        /// </remarks>
        /// <param name="name">Nombre del nuevo segmento.</param>
        /// <param name="description">Descripción del nuevo segmento.</param>
        public int CreateSegment( string name, string description )
        {
            try
            {
                using( SqlConnection SqlConn = new SqlConnection( _sqlConnectionString ) )
                {
                    SqlConn.Open( );
                    SqlCommand Cmd = new SqlCommand( );
                    Cmd.Connection = SqlConn;
                    Cmd.CommandType = System.Data.CommandType.StoredProcedure;
                    Cmd.CommandText = "dbo.aspnet_Membership_CreateSegment";
                    Cmd.Parameters.AddWithValue( "@ApplicationName", _applicationName );
                    Cmd.Parameters.AddWithValue( "@Name", name );
                    Cmd.Parameters.AddWithValue( "@Description", description );
                    Cmd.Parameters.AddWithValue( "@OrderNum", "0" );
                    //Parametro OUTPUT
                    SqlParameter NewParam = Cmd.Parameters.Add( "@SegmentId", System.Data.SqlDbType.Int );
                    NewParam.Direction = System.Data.ParameterDirection.Output;
                    //Parametro valor RETURN.
                    NewParam=Cmd.Parameters.Add("@RETURN_VALUE", System.Data.SqlDbType.Int);
                    NewParam.Direction=System.Data.ParameterDirection.ReturnValue;

                    Cmd.ExecuteNonQuery( );
                    if( (int)Cmd.Parameters["@RETURN_VALUE"].Value == 0 )
                    {
                        return Convert.ToInt32( Cmd.Parameters["@SegmentId"].Value );
                    }
                    else
                    {
                        throw new Exception( "Error en la creación del segmento" );
                    }

                }
            }
            catch( SqlException ex ) { throw ex; }
            catch( Exception ex ) { throw ex; }
        }
        public bool DeleteSegment( int segmentId )
        {
            try
            {
                using( SqlConnection SqlConn = new SqlConnection( _sqlConnectionString ) )
                {
                    SqlConn.Open( );
                    SqlCommand Cmd = new SqlCommand( );
                    Cmd.Connection = SqlConn;
                    Cmd.CommandType = System.Data.CommandType.StoredProcedure;
                    Cmd.CommandText = "dbo.aspnet_Membership_DeleteSegment";
                    Cmd.Parameters.AddWithValue( "@ApplicationName", _applicationName );
                    Cmd.Parameters.AddWithValue( "@SegmentId", segmentId );

                    
                    //Parametro valor RETURN.
                    SqlParameter NewParam = new SqlParameter( );
                    NewParam = Cmd.Parameters.Add( "@RETURN_VALUE", System.Data.SqlDbType.Int );
                    NewParam.Direction = System.Data.ParameterDirection.ReturnValue;

                    Cmd.ExecuteNonQuery( );
                    if( (int)Cmd.Parameters["@RETURN_VALUE"].Value == 0 )
                    {
                        //Borrador correctamente.
                        return true;
                    }
                    else
                    {
                        throw new Exception( "Error en el borrado del segmento" );
                    }

                }
            }
            catch( SqlException ex ) { throw ex; }
            catch( Exception ex ) { throw ex; }
        }
        public bool UpdateSegment( int segmentId, string name )
        {
            throw new System.NotImplementedException( );
        }
        public bool UpdateSegment( int segmentId, string name, string description )
        {
            throw new System.NotImplementedException( );
        }
        public bool AddMembershipUserToSegment( int userId, int segmentId )
        {
            throw new System.NotImplementedException( );
        }
        public bool AddMembershipUserCollectionToSegment( MembershipUserCollection muCollection, int segmentId )
        {
            throw new System.NotImplementedException( );
        }
        public bool RemoveMembershipUserFromSegment( MembershipUser user, int segmentId )
        {
            throw new System.NotImplementedException( );
        }
        public bool RemoveMembershipUserCollectionFromSegment( MembershipUserCollection muCollection, int segmentId )
        {
            throw new System.NotImplementedException( );
        }
        /// <summary>
        /// Realiza una operación AND sobre 2 segmentos, generando un nuevo segmento con el resultado de la operación.
        /// </summary>
        /// <remarks>Se generará un nombre de segmento de forma automática.</remarks>
        /// <param name="firstSourceSegment1Id">Primer segmento origen.</param>
        /// <param name="secondSourceSegmentId">Segundo segmento origen.</param>
        public bool FillAndSegment( int firstSourceSegmentId, int secondSourceSegmentId, int destinationSegmentId, bool overwrite )
        {
            try
            {
                using( SqlConnection SqlConn = new SqlConnection( _sqlConnectionString ) )
                {
                    SqlConn.Open( );
                    SqlCommand Cmd = new SqlCommand( );
                    Cmd.Connection = SqlConn;
                    Cmd.CommandType = System.Data.CommandType.StoredProcedure;
                    Cmd.CommandText = "dbo.aspnet_Membership_FillAndSegment";
                    Cmd.Parameters.AddWithValue( "@SegmentSourceId_A", firstSourceSegmentId );
                    Cmd.Parameters.AddWithValue( "@SegmentSourceId_B", secondSourceSegmentId );
                    Cmd.Parameters.AddWithValue( "@SegmentDestinationId", destinationSegmentId );
                    SqlParameter NewParam = new SqlParameter( );
                    //Parametro valor RETURN.
                    NewParam = Cmd.Parameters.Add( "@RETURN_VALUE", System.Data.SqlDbType.Int );
                    NewParam.Direction = System.Data.ParameterDirection.ReturnValue;

                    Cmd.ExecuteNonQuery( );
                    if( (int)Cmd.Parameters["@RETURN_VALUE"].Value == 0 )
                    {
                        return true;
                    }
                    else
                    {
                        throw new Exception( string.Format("Error {0} en la operación del llenado del segmento", Cmd.Parameters["@RETURN_VALUE"].Value));
                    }

                }
            }
            catch( SqlException ex ) { throw ex; }
            catch( Exception ex ) { throw ex; }
        }
        public bool FillNandSegment( int firstSourceSegmentId, int secondSourceSegmentId, int destinationSegmentId, bool overwrite )
        {
            try
            {
                using( SqlConnection SqlConn = new SqlConnection( _sqlConnectionString ) )
                {
                    SqlConn.Open( );
                    SqlCommand Cmd = new SqlCommand( );
                    Cmd.Connection = SqlConn;
                    Cmd.CommandType = System.Data.CommandType.StoredProcedure;
                    Cmd.CommandText = "dbo.aspnet_Membership_FillNAndSegment";
                    Cmd.Parameters.AddWithValue( "@SegmentSourceId_A", firstSourceSegmentId );
                    Cmd.Parameters.AddWithValue( "@SegmentSourceId_B", secondSourceSegmentId );
                    Cmd.Parameters.AddWithValue( "@SegmentDestinationId", destinationSegmentId );
                    SqlParameter NewParam = new SqlParameter( );
                    //Parametro valor RETURN.
                    NewParam = Cmd.Parameters.Add( "@RETURN_VALUE", System.Data.SqlDbType.Int );
                    NewParam.Direction = System.Data.ParameterDirection.ReturnValue;

                    Cmd.ExecuteNonQuery( );
                    if( (int)Cmd.Parameters["@RETURN_VALUE"].Value == 0 )
                    {
                        return true;
                    }
                    else
                    {
                        throw new Exception( string.Format( "Error {0} en la operación de llenado del segmento", Cmd.Parameters["@RETURN_VALUE"].Value ) );
                    }

                }
            }
            catch( SqlException ex ) { throw ex; }
            catch( Exception ex ) { throw ex; }
        }
        /// <summary>
        /// Realiza una operación OR de 2 segmentos origen en el segmento de destino específicado. Se sobreescribe el segmento de destino si el parametro "overwrite" es true.
        /// </summary>
        /// <param name="firstSourceSegmentId">Segmento de origen primario.</param>
        /// <param name="secondSourceSegmentId">Segmento de origen secundario.</param>
        /// <param name="destinationSegmentId">Segmento de destino.</param>
        /// <param name="overwrite">Indicador que determina si sobreescribe el segmento de destino.</param>
        public bool FillSumSegment( int firstSourceSegmentId, int secondSourceSegmentId, int destinationSegmentId, bool overwrite )
        {
            try
            {
                using( SqlConnection SqlConn = new SqlConnection( _sqlConnectionString ) )
                {
                    SqlConn.Open( );
                    SqlCommand Cmd = new SqlCommand( );
                    Cmd.Connection = SqlConn;
                    Cmd.CommandType = System.Data.CommandType.StoredProcedure;
                    Cmd.CommandText = "dbo.aspnet_Membership_FillSumSegment";
                    Cmd.Parameters.AddWithValue( "@SegmentSourceId_A", firstSourceSegmentId );
                    Cmd.Parameters.AddWithValue( "@SegmentSourceId_B", secondSourceSegmentId );
                    Cmd.Parameters.AddWithValue( "@SegmentDestinationId", destinationSegmentId );
                    SqlParameter NewParam = new SqlParameter( );
                    //Parametro valor RETURN.
                    NewParam = Cmd.Parameters.Add( "@RETURN_VALUE", System.Data.SqlDbType.Int );
                    NewParam.Direction = System.Data.ParameterDirection.ReturnValue;

                    Cmd.ExecuteNonQuery( );
                    if( (int)Cmd.Parameters["@RETURN_VALUE"].Value == 0 )
                    {
                        return true;
                    }
                    else
                    {
                        throw new Exception( string.Format( "Error {0} en la operación de llenado del segmento", Cmd.Parameters["@RETURN_VALUE"].Value ) );
                    }

                }
            }
            catch( SqlException ex ) { throw ex; }
            catch( Exception ex ) { throw ex; }
        }
        public bool FillSubstractSegment( int firstSourceSegmentId, int secondSourceSegmentId, int destinationSegmentId, bool overwrite )
        {
            try
            {
                using( SqlConnection SqlConn = new SqlConnection( _sqlConnectionString ) )
                {
                    SqlConn.Open( );
                    SqlCommand Cmd = new SqlCommand( );
                    Cmd.Connection = SqlConn;
                    Cmd.CommandType = System.Data.CommandType.StoredProcedure;
                    Cmd.CommandText = "dbo.aspnet_Membership_FillSubstractSegment";
                    Cmd.Parameters.AddWithValue( "@SegmentSourceId_A", firstSourceSegmentId );
                    Cmd.Parameters.AddWithValue( "@SegmentSourceId_B", secondSourceSegmentId );
                    Cmd.Parameters.AddWithValue( "@SegmentDestinationId", destinationSegmentId );
                    SqlParameter NewParam = new SqlParameter( );
                    //Parametro valor RETURN.
                    NewParam = Cmd.Parameters.Add( "@RETURN_VALUE", System.Data.SqlDbType.Int );
                    NewParam.Direction = System.Data.ParameterDirection.ReturnValue;

                    Cmd.ExecuteNonQuery( );
                    if( (int)Cmd.Parameters["@RETURN_VALUE"].Value == 0 )
                    {
                        return true;
                    }
                    else
                    {
                        throw new Exception( string.Format( "Error {0} en la operación de llenado del segmento", Cmd.Parameters["@RETURN_VALUE"].Value ) );
                    }

                }
            }
            catch( SqlException ex ) { throw ex; }
            catch( Exception ex ) { throw ex; }
        } 
        public MembershipUserCollection GetMembershipUsersBySegment( int segmentId )
        {
            throw new System.NotImplementedException( );
        }
        /// <summary>
        /// Crea un nuevo grupo de segmentos, el grupo de segmentos tiene una propiedad de
        /// borrado lógico (FlagDeleted) que se establece de forma predeterminada a False.
        /// </summary>
        /// <returns>Devuelve el identificador del nuevo segmento.</returns>
        /// <remarks>
        /// El valor de ordenamiento de cada grupo de segmentos creado se establece
        /// automáticamente al crearlo con el valor máximo existente.
        /// </remarks>
        /// <param name="name">Nombre del grupo de segmentos.</param>
        /// <param name="description">Descripción del nuevo grupo de segmentos.</param>
        public int CreateSegmentGroup( string name, string description)
        {
            using( SqlConnection SqlConn = new SqlConnection( _sqlConnectionString ) )
            {
                SqlConn.Open( );
                SqlCommand Cmd = new SqlCommand( );
                Cmd.Connection = SqlConn;
                Cmd.CommandType = System.Data.CommandType.StoredProcedure;
                Cmd.CommandText = "dbo.aspnet_Membership_CreateSegmentGroup";
                Cmd.Parameters.AddWithValue( "@ApplicationName", _applicationName );
                Cmd.Parameters.AddWithValue( "@Name", name );
                Cmd.Parameters.AddWithValue( "@Description", description );
                Cmd.Parameters.AddWithValue( "@OrderNum", "0" );
                //Parametro OUTPUT
                SqlParameter NewParam = Cmd.Parameters.Add( "@SegmentGroupId", System.Data.SqlDbType.Int );
                NewParam.Direction = System.Data.ParameterDirection.Output;
                //Parametro valor RETURN.
                NewParam = Cmd.Parameters.Add( "@RETURN_VALUE", System.Data.SqlDbType.Int );
                NewParam.Direction = System.Data.ParameterDirection.ReturnValue;

                Cmd.ExecuteNonQuery( );
                if( (int)Cmd.Parameters["@RETURN_VALUE"].Value == 0 )
                {
                    return Convert.ToInt32( Cmd.Parameters["@SegmentGroupId"].Value );
                }
                else
                {
                    throw new Exception( "Error en la creación del grupo de segmentos" );
                }

            }
        }
        public bool UpdateSegmentGroup( int segmentGroupId, string name )
        {
            throw new System.NotImplementedException( );
        }

        public bool UpdateSegmentGroup( int segmentGroupId, string name, string description )
        {
            throw new System.NotImplementedException( );
        }
    
        public bool DeleteSegmentGroup( )
        {
            throw new System.NotImplementedException( );
        }
        public MembershipSegmentCollection GetAllSegments( )
        {
            throw new System.NotImplementedException( );
        }
        public IEnumerable GetAllSegmentGroups( )
        {
            throw new System.NotImplementedException( );
        }
        public IEnumerable GetSegmentsInGroup( )
        {
            throw new System.NotImplementedException( );
        }
        public bool RemoveSegmentFromGroup( )
        {
            throw new System.NotImplementedException( );
        }
        public bool AddSegmentToSegmentGroup( )
        {
            throw new System.NotImplementedException( );
        }
        public bool RemoveAllMembershipUsersFromSegment( )
        {
            throw new System.NotImplementedException( );
        }
        public bool RemoveAllSegmentsFromGroup( )
        {
            throw new System.NotImplementedException( );
        }
        public bool LockSegment( )
        {
            throw new System.NotImplementedException( );
        }
        public bool UnlockSegment( )
        {
            throw new System.NotImplementedException( );
        }


    }

    



    
}
